﻿using Library.Core.Infrastructure.EntityFrameworkDataAccess;
using Library.Core.Infrastructure.PersistenceObject;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace Synthesize.Infrastructure.EFDataAccess
{
    /// <summary>
    /// 数据库连接上下文
    /// </summary>
    public class SynthesizeContext : List<DbContext>, IEFContext
    {
        private SynthesizeContextReadOnly _readOnlyContext;
        private SynthesizeContextReadWrite _readWriteContext;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="readOnlyContext"></param>
        /// <param name="readWriteContext"></param>
        public SynthesizeContext(SynthesizeContextReadOnly readOnlyContext, SynthesizeContextReadWrite readWriteContext)
        {
            _readOnlyContext = readOnlyContext;
            _readWriteContext = readWriteContext;
        }

        public IEnumerable<DbContext> Get()
        {
            yield return _readOnlyContext;
            yield return _readWriteContext;
        }
    }

    /// <summary>
    /// 拆分为微服务模块后的工程后，则分离命名为 xxxContext
    /// </summary>
    public abstract class SynthesizeBaseContext<T> : DbContext where T : DbContext
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="options"></param>
        public SynthesizeBaseContext(DbContextOptions<T> options) : base(options)
        {

        }
        /// <summary>
        /// 创建Model
        /// </summary>
        /// <param name="modelBuilder"></param>
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {

            var assemblies = new[] { Assembly.GetExecutingAssembly() }; //单体架构只获取当前程序集
            //动态创建DbSet：
            foreach (var assembly in assemblies)
            {
                foreach (Type type in assembly.ExportedTypes)
                {
                    if (type.IsClass && type != typeof(PersistenceObjectBase) && typeof(PersistenceObjectBase).IsAssignableFrom(type))
                    {
                        var method = modelBuilder.GetType().GetMethods().Where(x => x.Name == "Entity").FirstOrDefault();

                        if (method != null)
                        {
                            method = method.MakeGenericMethod(new Type[] { type });
                            method.Invoke(modelBuilder, null);
                        }
                    }
                }
            }

            base.OnModelCreating(modelBuilder);
        }
    }


}
